package amit.browser;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Logger;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;

//import org.jdesktop.jdic.browser.BrowserEngineManager;
//import org.jdesktop.jdic.browser.IWebBrowser;
import org.jdesktop.jdic.browser.WebBrowser;
import org.jdesktop.jdic.browser.WebBrowserEvent;
import org.jdesktop.jdic.browser.WebBrowserListener;

import amit.util.GuiUtil;

/**
 * The Browser - JDIC API main class Enable our users to see the url that its
 * editing
 * 
 * @author ido
 */
public class Browser extends JPanel {

	
	private Logger logger = Logger.getLogger("amit.GuiUtil");
	
	private JToolBar browserToolBar = new JToolBar();
	public static ImageIcon browseIcon = GuiUtil.sharedInstance.loadIcon("/browser_images/Right.gif");
	private JButton stopButton = new JButton(GuiUtil.sharedInstance.loadIcon("/browser_images/Stop.png")); // "Stop",
	private JButton refreshButton = new JButton(GuiUtil.sharedInstance
			.loadIcon("/browser_images/Reload.png")); // "Refresh",
	private JButton forwardButton = new JButton(GuiUtil.sharedInstance
			.loadIcon("/browser_images/Forward.png")); // "Forward",
	private JButton backButton = new JButton(GuiUtil.sharedInstance
			.loadIcon("/browser_images/Back.png")); // "Back",

	// private JButton stopRespButton = new
	// JButton(GuiUtil.sharedInstance.loadIcon("/gft16_1.gif"));
	// On default the browser show pages according to table selection.
	// if the user wish to stop it... this is the flag for it.
	// private boolean isBrowserResp = true;
	// private Color baseStopRepsColor;

	private JButton popupButton = new JButton(GuiUtil.sharedInstance
			.loadIcon("/browser_images/Back.png")); // "Back",

	private JPanel addressPanel = new JPanel();
	private JLabel addressLabel = new JLabel();
	private JTextField addressTextField = new JTextField();
	private JButton goButton = new JButton();
	private JPanel addrToolBarPanel = new JPanel();

	/**
	 * The status bar
	 */
	private BrowserStatusBar statusBar = new BrowserStatusBar();

	private JPanel browserPanel = new JPanel();

	private WebBrowser webBrowser;

	/**
	 * Ctor
	 */
	public Browser() {
		try {
			initGui();
		} catch (Exception e) {
			logger.severe("Could not init the browser! ex:"
					+ GuiUtil.sharedInstance.stackToString(e));
		}

	}

	public Browser(URL url) {
		try {
			// WebBrowser.setDebug(true);
			initGui();
		} catch (Exception e) {
			logger.severe("Could not init the browser! with url:"
					+ url.toString() + " ex:"
					+ GuiUtil.sharedInstance.stackToString(e));
		}
	}

	/**
	 * Unit test
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) {
		try {
			//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

			JFrame frame = new JFrame("RQCC Browser");
			Container contentPane = frame.getContentPane();
			contentPane.setLayout(new BorderLayout());
			Browser bro = new Browser();
			bro.setPreferredSize(new Dimension(600,500));
			contentPane.add(bro, BorderLayout.CENTER);

			frame.addWindowListener(new WindowAdapter() {
				public void windowClosing(WindowEvent e) {
					System.exit(0);
				}
			});

			frame.pack();
			frame.setVisible(true);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @throws Exception
	 */
	private void initGui() throws Exception {
		setLayout(new BorderLayout());

		ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);

		addressLabel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
		addressLabel.setToolTipText("Enter the url you wish to check");
		addressLabel.setText(" URL: ");

		goButton.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(
				0, 2, 0, 2), new EtchedBorder()));
		goButton.setMaximumSize(new Dimension(60, 25));
		goButton.setMinimumSize(new Dimension(60, 25));
		goButton.setPreferredSize(new Dimension(60, 25));
		goButton.setToolTipText("Load the given URL");
		goButton.setIcon(browseIcon);
		goButton.setText("GO");
		goButton.addActionListener(new Browser_jGoButton_actionAdapter(this));

		addressPanel.setLayout(new BorderLayout());

		addressTextField
				.addActionListener(new Browser_jAddressTextField_actionAdapter(
						this));

		backButton.setToolTipText("Go back one page");
		backButton.setHorizontalTextPosition(SwingConstants.TRAILING);
		backButton.setEnabled(false);
		// backButton.setMaximumSize(new Dimension(75, 27));
		// backButton.setPreferredSize(new Dimension(75, 27));
		backButton
				.addActionListener(new Browser_jBackButton_actionAdapter(this));
		forwardButton.setToolTipText("Go forward one page");
		forwardButton.setEnabled(false);
		forwardButton
				.addActionListener(new Browser_jForwardButton_actionAdapter(
						this));
		refreshButton.setToolTipText("Reload current page");
		refreshButton.setEnabled(true);
		// refreshButton.setMaximumSize(new Dimension(75, 27));
		// refreshButton.setMinimumSize(new Dimension(75, 27));
		// refreshButton.setPreferredSize(new Dimension(75, 27));
		refreshButton
				.addActionListener(new Browser_jRefreshButton_actionAdapter(
						this));
		stopButton
				.setToolTipText("Loading pages. Click here to stop fetching web sites");
		stopButton.setVerifyInputWhenFocusTarget(true);
		stopButton.setEnabled(true);

		stopButton
				.addActionListener(new Browser_jStopButton_actionAdapter(this));

		addressPanel.add(addressLabel, BorderLayout.WEST);
		addressPanel.add(addressTextField, BorderLayout.CENTER);
		addressPanel.add(goButton, BorderLayout.EAST);
		addressPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
				.createEtchedBorder(), BorderFactory.createEmptyBorder(2, 0, 2,
				0)));

		browserToolBar.setFloatable(false);
		browserToolBar.add(backButton, null);
		browserToolBar.add(forwardButton, null);
		browserToolBar.addSeparator();
		browserToolBar.add(refreshButton, null);
		browserToolBar.add(stopButton, null);
		browserToolBar.addSeparator();
		browserToolBar.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createEtchedBorder(), BorderFactory
						.createEmptyBorder(2, 2, 2, 0)));

		addrToolBarPanel.setLayout(new BorderLayout());
		addrToolBarPanel.add(addressPanel, BorderLayout.CENTER);
		addrToolBarPanel.add(browserToolBar, BorderLayout.WEST);
		addrToolBarPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));

		statusBar.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
		statusBar.setDesc("The Ads Browser");
		
		//BrowserEngineManager bem = BrowserEngineManager.instance();
		//bem.setActiveEngine(BrowserEngineManager.IE);
        //webBrowser = bem.getActiveEngine().getWebBrowser();
        
		//WebBrowser.setDebug(true);
  
		webBrowser = new WebBrowser(); //false);

        /**
		 * @@author ido webBrowser.setDebug(true);
		 */
		webBrowser.addWebBrowserListener(new WebBrowserListener() {
			public void downloadStarted(WebBrowserEvent event) {
				updateStatusInfo("Loading started.");
			}

			public void downloadCompleted(WebBrowserEvent event) {
				backButton.setEnabled(webBrowser.isBackEnabled());
				forwardButton.setEnabled(webBrowser.isForwardEnabled());

				updateStatusInfo("Loading completed.");
				URL currentUrl = webBrowser.getURL();

				if (currentUrl != null) {
					addressTextField.setText(currentUrl.toString());
				}
			}

			public void downloadProgress(WebBrowserEvent event) {
				// updateStatusInfo("Loading in progress...");
			}

			public void downloadError(WebBrowserEvent event) {
				updateStatusInfo("Loading error.");
			}

			public void documentCompleted(WebBrowserEvent event) {
				updateStatusInfo("Document loading completed.");
			}

			public void titleChange(WebBrowserEvent event) {
				updateStatusInfo("Title of the browser window changed.");
			}

			public void statusTextChange(WebBrowserEvent event) {
				// updateStatusInfo("Status text changed.");
			}

			public void initializationCompleted(WebBrowserEvent event) {
				System.out.println("browser init done");
			}

			public void windowClose(WebBrowserEvent arg0) {
				System.out.println("browser window closed");
			}
		});

		browserPanel.setLayout(new BorderLayout());
		browserPanel.add(webBrowser, BorderLayout.CENTER);
		browserPanel.setMinimumSize(new Dimension(100,100));
		add(browserPanel, BorderLayout.CENTER);
		add(addrToolBarPanel, BorderLayout.NORTH);
		add(statusBar, BorderLayout.SOUTH);
	}

	/**
	 * 
	 * @param statusMessage
	 */
	protected void updateStatusInfo(String statusMessage) {
		statusBar.setStatus(statusMessage);
	}

	/**
	 * 
	 * @param url
	 */
	public void loadUrl(final String curUrl)  {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					webBrowser.setURL(new URL(curUrl));
					updateStatusInfo("Loading " + curUrl + "...");
				} catch (Exception e) {
					logger.severe("could not parse: " + curUrl
							+ " url as valid");
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Check the current input URL string in the address text field, load it,
	 * and update the status info and toolbar info.
	 */
	protected void loadURL() {
		String inputValue = addressTextField.getText();

		if (inputValue == null) {
			JOptionPane.showMessageDialog(this, "The given URL is NULL:",
					"Warning", JOptionPane.WARNING_MESSAGE);
		} else {
			// Check if the text value is a URL string.
			URL curUrl = null;

			try {
				// Check if the input string is a local path by checking if it
				// starts with a driver name(on Windows) or root path(on Unix).
				File[] roots = File.listRoots();

				for (int i = 0; i < roots.length; i++) {
					if (inputValue.toLowerCase().startsWith(
							roots[i].toString().toLowerCase())) {
						File curLocalFile = new File(inputValue);
						curUrl = curLocalFile.toURL();
						break;
					}
				}

				if (curUrl == null) {
					// Check if the text value is a valid URL.
					try {
						curUrl = new URL(inputValue);
					} catch (MalformedURLException e) {
						if (inputValue.toLowerCase().startsWith("ftp.")) {
							curUrl = new URL("ftp://" + inputValue);
						} else if (inputValue.toLowerCase().startsWith(
								"gopher.")) {
							curUrl = new URL("gopher://" + inputValue);
						} else {
							curUrl = new URL("http://" + inputValue);
						}
					}
				}

				webBrowser.setURL(curUrl);

				// Update the address text field, statusbar, and toolbar info.
				updateStatusInfo("Loading " + curUrl.toString() + " ......");

			} catch (MalformedURLException mue) {
				JOptionPane.showMessageDialog(this,
						"The given URL is not valid:" + inputValue, "Warning",
						JOptionPane.WARNING_MESSAGE);
			}
		}
	}

	void jGoButton_actionPerformed(ActionEvent e) {
		loadURL();
	}

	void jAddressTextField_actionPerformed(ActionEvent e) {
		loadURL();
	}

	void jBackButton_actionPerformed(ActionEvent e) {
		webBrowser.back();
	}

	void jForwardButton_actionPerformed(ActionEvent e) {
		webBrowser.forward();
	}

	void jRefreshButton_actionPerformed(ActionEvent e) {
		webBrowser.refresh();
	}

	void jStopButton_actionPerformed(ActionEvent e) {
		webBrowser.stop();
	}

	public WebBrowser getWebBrowser() {
		return webBrowser;
	}

}

/**
 * 
 * @author ido
 * 
 */
class Browser_jAddressTextField_actionAdapter implements
		java.awt.event.ActionListener {
	Browser adaptee;

	Browser_jAddressTextField_actionAdapter(Browser adaptee) {
		this.adaptee = adaptee;
	}

	public void actionPerformed(ActionEvent e) {
		adaptee.jAddressTextField_actionPerformed(e);
	}
}

class Browser_jBackButton_actionAdapter implements
		java.awt.event.ActionListener {
	Browser adaptee;

	Browser_jBackButton_actionAdapter(Browser adaptee) {
		this.adaptee = adaptee;
	}

	public void actionPerformed(ActionEvent e) {
		adaptee.jBackButton_actionPerformed(e);
	}
}

class Browser_jForwardButton_actionAdapter implements
		java.awt.event.ActionListener {
	Browser adaptee;

	Browser_jForwardButton_actionAdapter(Browser adaptee) {
		this.adaptee = adaptee;
	}

	public void actionPerformed(ActionEvent e) {
		adaptee.jForwardButton_actionPerformed(e);
	}
}

/**
 * 
 * @author ido
 * 
 */
class Browser_jRefreshButton_actionAdapter implements
		java.awt.event.ActionListener {
	Browser adaptee;

	Browser_jRefreshButton_actionAdapter(Browser adaptee) {
		this.adaptee = adaptee;
	}

	public void actionPerformed(ActionEvent e) {
		adaptee.jRefreshButton_actionPerformed(e);
	}
}

/**
 * 
 * @author ido
 * 
 */
class Browser_jStopButton_actionAdapter implements
		java.awt.event.ActionListener {
	Browser adaptee;

	Browser_jStopButton_actionAdapter(Browser adaptee) {
		this.adaptee = adaptee;
	}

	public void actionPerformed(ActionEvent e) {
		adaptee.jStopButton_actionPerformed(e);
	}
}

/**
 * 
 * @author ido
 * 
 */
class Browser_jGoButton_actionAdapter implements java.awt.event.ActionListener {
	Browser adaptee;

	Browser_jGoButton_actionAdapter(Browser adaptee) {
		this.adaptee = adaptee;
	}

	public void actionPerformed(ActionEvent e) {
		adaptee.jGoButton_actionPerformed(e);
	}

}
